﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure.Internal;



namespace Model.Core.Entity.Dbcontexts
{
    public class DbcontextBase : DbContext, IDisposable
    {
        private readonly ILogger<DbcontextBase> _logger;

        public DbSet<PackingBoxDetail> PackingBoxDetail { get; set; }
        public DbSet<RobotInfo> RobotInfo { get; set; }
        public DbSet<MapInfo> MapInfo { get; set; }
        public DbSet<JobInfo> JobInfo { get; set; }
        public DbSet<JobNodeInfo> JobNodeInfo { get; set; }
        public DbSet<PointInfo> PointInfo { get; set; }
        public DbSet<JobRecord> JobRecord { get; set; }
        public DbSet<JobCronInfo> JobCroninfo { get; set; }
        public DbSet<DevLog> DevLog { get; set; }
        public DbSet<RobotType> RobotType { get; set; }

        public DbcontextBase(DbContextOptions<DbcontextBase> dbContextOptions, ILogger<DbcontextBase> logger) : base(dbContextOptions)
        {
            _logger = logger;
            try
            {
                InitDatabase();
            }
            catch (Exception ex)
            {
                _logger.LogCritical(ex, "Failed to initialize the database. The application may not function correctly.");
                throw;
            }
        }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            try
            {
                base.OnConfiguring(options);
            }
            catch (InvalidOperationException ex)
            {
                var connectionString = options.Options.GetExtension<MySqlOptionsExtension>()?.ConnectionString;
                _logger.LogError(ex, $"Invalid operation while configuring the database context. Connection string: {connectionString}. Check the connection string or configuration.");
                throw;
            }
            catch (Exception ex)
            {
                var connectionString = options.Options.GetExtension<MySqlOptionsExtension>()?.ConnectionString;
                _logger.LogError(ex, $"Unexpected error while configuring the database context. Connection string: {connectionString}.");
                throw;
            }
        }

        private void InitDatabase()
        {
            try
            {
                var isCreated = this.Database.EnsureCreated();
                if (isCreated)
                {
                    _logger.LogInformation("Database created successfully.");
                }
                else
                {
                    _logger.LogDebug("Database already exists.");
                }
            }
            catch (DbUpdateException ex)
            {
                _logger.LogError(ex, "Error while creating or updating the database. Check the database schema or permissions.");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Unexpected error while ensuring the database is created.");
                throw;
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            try
            {
                base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<RobotType>()
                .ToTable("rbottype")
                .HasData(
                new RobotType { Id = new Guid("a7d1e8b4-2c3d-4e5f-9a6b-7c8d9e0f1a2b"), Name = "搬运机器人", Description = "用于物料搬运的机器人", Key = "CarryRobot" },
                new RobotType { Id = new Guid("b8e2f9c5-3d4e-6f7a-8b9c-9d0e1f2a3b4c"), Name = "堆垛机器人", Description = "用于仓储堆垛的机器人", Key = "StackerRobot" },
                new RobotType { Id = new Guid("c9f0e1d2-4e5f-7a8b-9c0d-1e2f3a4b5c6d"), Name = "巡检机器人", Description = "用于设备巡检的机器人", Key = "PatrolRobot" },
                new RobotType { Id = new Guid("d0e1f2a3-5f6b-8c9d-1e2f-3a4b5c6d7e8f"), Name = "通用机器人", Description = "多功能通用型机器人", Key = "CommonRobot" }
            );
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError(ex, "Invalid operation while creating the database model. Check the entity configurations.");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Unexpected error while creating the database model.");
                throw;
            }
        }

        public override void Dispose()
        {
            try
            {
                base.Dispose();
                _logger.LogDebug("Database context disposed successfully.");
            }
            catch (ObjectDisposedException ex)
            {
                _logger.LogWarning(ex, "Attempted to dispose an already disposed database context.");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Unexpected error while disposing the database context.");
                throw;
            }
        }
    }
}
